package com.sping.gobang.common.api;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.sping.gobang.common.constant.Constants;
import com.sping.gobang.game.Matcher;
import com.sping.gobang.game.OnlineUserManager;
import com.sping.gobang.pojo.datapbject.User;
import com.sping.gobang.pojo.request.MatchRequest;
import com.sping.gobang.pojo.response.MatchResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

@Component
@Slf4j
//通过这个类来处理匹配功能中的websocket的请求
public class MatchAPI extends TextWebSocketHandler {
//    private ObjectMapper objectMapper=new ObjectMapper();
    @Autowired
    private OnlineUserManager onlineUserManager;
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private Matcher matcher;



    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        User user = (User) session.getAttributes().get(Constants.SESSION_USER_KEY);
        //       我这里的user绝对不可能未null，因为我用了令牌和统一登陆拦截的,既不可能直接访问game_hall.html
//        判断当前用户是否已经登陆过（已经是在线状态），如果是在线状态就不该进行后续逻辑操作了
        if(onlineUserManager.getFromGameHall(user.getUserId())!=null||onlineUserManager
                .getFromGameRoom(user.getUserId())!=null){
//      当前用户已经登陆
            MatchResponse response=new MatchResponse();
            response.setOk(true);
            response.setReason("当前禁止多开!");
            response.setMessage("repeatConnection");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(response)));
            //此处直接关闭太过激进，返回一个特殊的message，由客户端来进行判断，由客户端进行处理
//            session.close();
            return;
        }
        onlineUserManager.enterGameHall(user.getUserId(),session);
        log.info("玩家"+user.getUsername()+"进入游戏大厅!");

    }

    @Override
    protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
       User user = (User) session.getAttributes().get(Constants.SESSION_USER_KEY);
//       获取到客户端给服务器发送的数据,从消息的载荷里面获取数据
//        当前这个数据载荷是一个JSON格式的字符串，需要把它转化成java对象
        String payload = message.getPayload();
        MatchRequest matchRequest = objectMapper.readValue(payload, MatchRequest.class);
        MatchResponse matchResponse=new MatchResponse();
        if(matchRequest.getMessage().equals("startMatch")){
//            进入匹配队列
//            思路：创建一个类表示匹配队列，把当前用户给加进去,把玩家信息放入匹配队列之后，就可以返回一个响应给客户端了
            matcher.add(user);
            matchResponse.setOk(true);
            matchResponse.setMessage("startMatch");

        }else if(matchRequest.getMessage().equals("stopMatch")){
//            退出匹配队列
//            思路：创建一个类表示匹配队列，把当前用户从队列中移除,移除之后就可以返回一个响应给客户端了
            matcher.remove(user);
            matchResponse.setOk(true);
            matchResponse.setMessage("stopMatch");
        }else{//非法情况
            matchResponse.setOk(false);
            matchResponse.setReason("非法的匹配请求");
        }
        String jsonString = objectMapper.writeValueAsString(matchResponse);
        session.sendMessage(new TextMessage(jsonString));

    }

    @Override
    public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
//        游戏出错
        User user = (User) session.getAttributes().get(Constants.SESSION_USER_KEY);
        WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(tmpSession==session){
            onlineUserManager.exitGameHall(user.getUserId());
        }
        matcher.remove(user);

    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
//        游戏关闭
        User user = (User) session.getAttributes().get(Constants.SESSION_USER_KEY);
        WebSocketSession tmpSession = onlineUserManager.getFromGameHall(user.getUserId());
        if(session==tmpSession){
            onlineUserManager.exitGameHall(user.getUserId());
        }
        matcher.remove(user);
    }
}
